/******************************************************************************

    Simple Authentication and Authorisation System (SAAS)

    saas-test-user-info.c

    Copyright (C) 2011  Josh Goes


    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

    If you require a mailing address for this software, please send your
    mail to the following address:
        SAAS
        GPO Box 2973
        BRISBANE QLD 4001
        AUSTRALIA

******************************************************************************/


#include "saas.h"
#include "tests.h"

#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <stdlib.h>


char     opt_username[SAAS_MAX_USERNAME_LEN];
uint32_t opt_uid = 0;
uint8_t  opt_groups = 0;
uint8_t  opt_all_groups = 0;
uint8_t  opt_log_level = LOG_INFO;
uint8_t  show_help = 0;


struct st_saas_test_opt opts[] = {
	{ "by-username" , "n"  , 1 , NULL , &opt_username   , SAAS_TEST_VAR_TYPE_STR    , 0         , NULL , sizeof( opt_username ) },
	{ "by-uid"      , "i"  , 1 , NULL , &opt_uid        , SAAS_TEST_VAR_TYPE_UINT32 , 0         , NULL , 0                      },
	{ "groups"      , "g"  , 0 , NULL , &opt_groups     , SAAS_TEST_VAR_TYPE_UINT8  , 1         , NULL , 0                      },
	{ "all-groups"  , "a"  , 0 , NULL , &opt_all_groups , SAAS_TEST_VAR_TYPE_UINT8  , 1         , NULL , 0                      },
	{ "debug"       , "d"  , 0 , NULL , &opt_log_level  , SAAS_TEST_VAR_TYPE_UINT8  , LOG_DEBUG , NULL , 0                      },
	{ "quiet"       , "q"  , 0 , NULL , &opt_log_level  , SAAS_TEST_VAR_TYPE_UINT8  , LOG_CRIT  , NULL , 0                      },
	{ "help"        , "h"  , 0 , NULL , &show_help      , SAAS_TEST_VAR_TYPE_UINT8  , 1         , NULL , 0                      },
	{ NULL          , NULL , 0 , NULL , NULL            , 0                         , 0         , NULL , 0                      }
};



int main( int argc , char **argv )
{
	memset( opt_username , 0 , sizeof( opt_username ) );
	if ( saas_get_opts( opts , argc , argv ) != SAAS_OP_SUCCESS )
	{
		printf( "%s: error: could not parse arguments\n" , argv[0] );
		return 2;
	}
	if ( show_help == 1 || argc == 1 )
	{
		printf( "%s: usage:  <--by-uid uid|--by-username username|--help> [--groups|--all-groups|--debug|--quiet]\n\n" , argv[0] );
		printf(
			"This program tests the SAAS system by requesting user information by either\nUID or username.\n\n"
			"    --by-uid uid              Specifies the UID that is being searched.\n"
			"    -i       uid\n\n"
			"    --by-username  username   Specifies the Username that is being searched.\n"
			"    -n             username\n\n"
			"    --groups                  Include group membership information in the\n"
			"                              response.\n"
			"    -g\n\n"
			"    --all-groups              Include all group membership information in the\n"
			"                              response, regardless of whether the user is a\n"
			"                              direct member of the group, or is a member by\n"
			"                              group-by-group relation.\n"
			"    -a\n\n"
			"    --debug                   Enable debugging mode. This products a LOT of\n"
			"                              output.\n"
			"    -d\n\n"
			"    --quiet                   Allow only the utmost critical errors to be\n"
			"                              displayed.\n"
			"    -q\n\n"
			"    --help                    Display this usage message.\n"
			"    -h\n\n"
		);
		return 1;
	}

	if ( strlen( opt_username ) == 0 && opt_uid == 0 )
	{
		printf( "%s: error: you must specify at least a username or a UID. see `%s --help` for details.\n" , argv[0] , argv[0] );
		return 2;
	}

	// ok checks are done.  on with the show.
	saas_t     inst;
	uint16_t   ret;

	if ( opt_log_level == LOG_DEBUG )
		printf( "spawning new SAAS instance with saas_init()...\n" );

	ret = saas_init( &inst , NULL , opt_log_level , SAAS_LOG_STDOUT , 0 , NULL );
	if ( ret != SAAS_OP_SUCCESS )
	{
		printf( "error whilst calling saas_init(): (%d) %s\n" , ret , saaserror( ret ) );
		return 3;
	}


	if ( opt_log_level == LOG_DEBUG )
		printf( "SAAS Instance debugging data:\n" );
	saas_dump( &inst , " - " );

	saas_user_info_t  *ui;

	if ( opt_log_level == LOG_DEBUG )
		printf( "Requesting user info from SAAS...\n" );

	if ( opt_all_groups && opt_uid > 0 )
		ret = saas_user_info_with_all_groups_by_uid( &inst , opt_uid , &ui );
	else if ( opt_all_groups && strlen( opt_username ) > 0 )
		ret = saas_user_info_with_all_groups_by_username( &inst , opt_username , &ui );
	else if ( opt_groups && opt_uid > 0 )
		ret = saas_user_info_with_groups_by_uid( &inst , opt_uid , &ui );
	else if ( opt_groups && strlen( opt_username ) > 0 )
		ret = saas_user_info_with_groups_by_username( &inst , opt_username , &ui );
	else if ( opt_uid > 0 )
		ret = saas_user_info_by_uid( &inst , opt_uid , &ui );
	else if ( strlen( opt_username ) > 0 )
		ret = saas_user_info_by_username( &inst , opt_username , &ui );

	if ( opt_log_level == LOG_DEBUG || ret != SAAS_OP_SUCCESS )
		printf( "saas_user_info_with_all_groups_by_uid request returned: (%d) %s\n" , ret , saaserror( ret ) );

	if ( opt_log_level != LOG_CRIT && ret == SAAS_OP_SUCCESS )
	{
		printf( "     username = %s\n" , ui->username    );
		printf( "          uid = %u\n" , ui->uid         );
		printf( "          gid = %u\n" , ui->gid         );
		printf( "     fullname = %s\n" , ui->fullname    );
		printf( "  displayname = %s\n" , ui->displayname );
		printf( "        fname = %s\n" , ui->fname       );
		printf( "        lname = %s\n" , ui->lname       );
		printf( "        email = %s\n" , ui->email       );
		printf( "     home_dir = %s\n" , ui->home_dir    );
		printf( "        shell = %s\n" , ui->shell       );
		uint16_t k;
		for ( k = 0 ; k < ui->num_groups ; k++ )
			printf( "        group = %d(%s)\n" , ui->groups[k]->gid , ui->groups[k]->groupname );
		free( ui );
	}

	return 0;
}


